#region GNU General Public License
// XEdit2D - XNA 2D Asset Editor
// Copyright (C) 2010  HurlBat Games

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace HurlBat.XEdit2D
{
    using Keys = Microsoft.Xna.Framework.Input.Keys;
    /// <summary>
    /// Example control inherits from GraphicsDeviceControl, which allows it to
    /// render using a GraphicsDevice. This control shows how to draw animating
    /// 3D graphics inside a WinForms application. It hooks the Application.Idle
    /// event, using this to invalidate the control, which will cause the animation
    /// to constantly redraw.
    /// </summary>
    class MapViewer : XnaControl
    {
        Stopwatch timer;
        SpriteBatch spriteBatch;
        HurlBat.Data2D.Map.Map map;
        Point currentPosition;
        string baseTile = @"E:\VisualStudio\Projects\StrategyEditor2D\Content\grass.png";

        // Determines how fast the map will scroll (pixels per arrow key press)
        sbyte iMapXScrollRate = 16;
        sbyte iMapYScrollRate = 12;
        // Variable to determine if we are still moving from the previous directional command
        short iMoveCount = 0;
        // What direction are we moving (0=up, 1=down, 2=left, 3=right)
        byte iMoveDirection = 0;
        private ushort mapDisplayWidth = 12;
        private ushort mapDisplayHeight = 16;
        private short mapXpos = 0;
        private short mapYpos = 0;
        // Sub-tile coordinates for Smooth Scrolling
        private short mapXOffset = 0;
        private short mapYOffset = 0;

        long totalElapsedTime = 0;

        Texture2D grass;

        /// <summary>
        /// Initializes the control.
        /// </summary>
        protected override void Initialize()
        {
            // Start the animation timer.
            timer = Stopwatch.StartNew();

            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Hook the idle event to constantly redraw our animation.
            Application.Idle += delegate { Invalidate(); };
        }

        /// <summary>
        /// Draws the control.
        /// </summary>
        protected override void Draw()
        {
            if (grass == null)
            {
                FileStream s = new FileStream(baseTile, FileMode.Open);
                grass = Texture2D.FromStream(GraphicsDevice, s);
                s.Close();
            }
            if (map == null)
            {
                map = new HurlBat.Data2D.Map.Map();
                map.New(100, 100);
            }

            if (map == null || map.Width == 0 && map.Height == 0) return;

            // The time since Update was called last
            //float elapsed = timer.ElapsedMilliseconds (float)gameTime.ElapsedGameTime.TotalSeconds;
            totalElapsedTime += timer.ElapsedMilliseconds;
            // Read and save the current Keyboard State
            KeyboardState ksKeyboardState = Keyboard.GetState();
            // If we AREN'T in the process of completing a smooth-scroll move...
            if (iMoveCount <= 0)
            {
                // Check to see if an arrow key is pressed.  If so, set the
                // iMoveDirection to indicate the direction we will be moving in,
                // and the iMoveCount to how many times we need to execute.
                if (ksKeyboardState.IsKeyDown(Keys.Up))
                {
                    iMoveDirection = 0;
                    iMoveCount = (short)(map.TileSet.TileSize.Y + iMapYScrollRate);
                }
                if (ksKeyboardState.IsKeyDown(Keys.Down))
                {
                    iMoveDirection = 1;
                    iMoveCount = (short)(map.TileSet.TileSize.Y + iMapYScrollRate);
                }
                if (ksKeyboardState.IsKeyDown(Keys.Left))
                {
                    iMoveDirection = 2;
                    iMoveCount = (short)(map.TileSet.TileSize.X + iMapXScrollRate);
                }
                if (ksKeyboardState.IsKeyDown(Keys.Right))
                {
                    iMoveDirection = 3;
                    iMoveCount = (short)(map.TileSet.TileSize.X + iMapXScrollRate);
                }
            }
            else
            {
                // If we ARE in the middle of a smooth-scroll move, update the 
                // Offsets and decrement the move count.
                if (iMoveDirection == 0) mapYOffset -= iMapYScrollRate;
                if (iMoveDirection == 1) mapYOffset += iMapYScrollRate;
                if (iMoveDirection == 0 || iMoveDirection == 1)
                {
                    if (iMoveCount < iMapYScrollRate) iMoveCount = 0;
                    else iMoveCount -= iMapYScrollRate;
                }
                if (iMoveDirection == 2) mapXOffset -= iMapXScrollRate;
                if (iMoveDirection == 3) mapXOffset += iMapXScrollRate;
                if (iMoveDirection == 2 || iMoveDirection == 3)
                {
                    if (iMoveCount < iMapXScrollRate) iMoveCount = 0;
                    else iMoveCount -= iMapXScrollRate;
                }
                // If we move off of a tile, change our map location to the next tile
                if (mapXOffset < 0) { mapXOffset = (short)map.TileSet.TileSize.X; mapXpos--; }
                if (mapXOffset > map.TileSet.TileSize.X) { mapXOffset = 0; mapXpos++; }
                if (mapYOffset < 0) { mapYOffset = (short)map.TileSet.TileSize.Y; mapYpos--; }
                if (mapYOffset > map.TileSet.TileSize.X) { mapYOffset = 0; mapYpos++; }
                // If we move off of the side of the map, "snap" back (player won't see a move at all)
                if (mapXpos < 0) { mapXpos = 0; iMoveCount = 0; mapXOffset = iMoveCount; }
                if (mapXpos > map.Width - mapDisplayWidth)
                {
                    mapXpos = (short)(map.Width - mapDisplayWidth);
                    mapXOffset = (short)map.TileSet.TileSize.X;
                    iMoveCount = 0;
                }
                if (mapYpos < 0) { mapYpos = 0; iMoveCount = 0; mapYOffset = iMoveCount; }
                if (mapYpos > map.TileSet.TileSize.Y - mapDisplayHeight)
                {
                    mapYpos = (short)(map.Height - mapDisplayHeight);
                    mapYOffset = (sbyte)map.TileSet.TileSize.Y;
                    iMoveCount = 0;
                }
            }

            Vector2 pos = new Vector2(100, 100);

            // TO BE USED FOR MOUSE INTERACTION
            //MouseState mouse = Mouse.GetState();
            //System.Drawing.Point p = this.PointToScreen(System.Drawing.Point.Empty);
            //int mouseX = mouse.X - p.X;
            //int mouseY = mouse.Y - p.Y;
            //Rectangle view = GraphicsDevice.Viewport.Bounds;
            //if (view.Contains(new Point(mouseX, mouseY)))
            //    pos = new Vector2(mouseX, mouseY);

            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

            spriteBatch.Draw(grass, pos, Color.White);
            spriteBatch.End();
        }
    }
}
